<template>
  <div class="tree-select-wrapper">
    <el-popover
      v-model="popoverVisible"
      placement="bottom-start"
      trigger="manual"
      popper-class="tree-select-popover"
      :width="popoverWidth"
      :append-to-body="true"
      :visible-arrow="false"
    >
      <!-- 树结构 -->
      <el-tree
        ref="tree"
        :data="treeData"
        :props="defaultProps"
        node-key="id"
        highlight-current
        @node-click="handleNodeClick"
        :expand-on-click-node="false"
        :default-expand-all="true"
      />

      <!-- 输入框触发器 -->
      <el-input
        slot="reference"
        v-model="selectedLabel"
        placeholder="请选择"
        readonly
        :disabled="disabled"
        @focus="popoverVisible = true"
      >
        <i slot="suffix" class="el-icon-arrow-down" />
      </el-input>
    </el-popover>
  </div>
</template>

<script>
export default {
  name: 'TreeSelect',
  props: {
    value: [String, Number], // v-model 双向绑定值
    data: {
      type: Array,
      default: () => [],
    },
    url: {
      type: String,
      default: '',
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    labelField: {
      type: String,
      default: 'label',
    },
    valueField: {
      type: String,
      default: 'id',
    },
    childrenField: {
      type: String,
      default: 'children',
    }
  },
  data() {
    return {
      treeData: [],
      selectedLabel: '',
      selectedId: null,
      popoverVisible: false,
      popoverWidth: 300,
      defaultProps: {
        label: this.labelField,
        children: this.childrenField,
      }
    };
  },
  watch: {
    data: {
      handler() {
        if (!this.url) {
          this.treeData = this.data;
          this.$nextTick(() => this.updateSelectedLabel());
        }
      },
      immediate: true
    },
    value: {
      handler() {
        this.selectedId = this.value;
        this.updateSelectedLabel();
      },
      immediate: true
    }
  },
  mounted() {
    this.setPopoverWidth();
    if (this.url) {
      this.fetchData();
    }
    window.addEventListener('resize', this.setPopoverWidth);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.setPopoverWidth);
  },
  methods: {
    fetchData() {
      this.$http.get(this.url)
        .then(res => {
          this.treeData = res.data;
          this.$nextTick(() => this.updateSelectedLabel());
        })
        .catch(e => {
          this.$message.error(e.message);
        });
    },
    setPopoverWidth() {
      this.$nextTick(() => {
        const input = this.$el.querySelector('.el-input');
        if (input) {
          this.popoverWidth = input.offsetWidth;
        }
      });
    },
    isLeafNode(node) {
      return !node[this.childrenField] || node[this.childrenField].length === 0;
    },
    handleNodeClick(data) {
      if (this.isLeafNode(data)) {
        this.selectedLabel = data[this.labelField];
        this.selectedId = data[this.valueField];

        // 触发 v-model
        this.$emit('input', this.selectedId);

        // 自定义事件（可选）
        this.$emit('handleChangeInput', this.selectedId);
        this.$emit('handleNodeChange', data);

        this.popoverVisible = false;
      } else {
        this.$message.warning('只能选择最底层节点');
      }
    },
    updateSelectedLabel() {
      if (!this.selectedId || !this.treeData.length) return;
      this.setLabelById(this.selectedId, this.treeData);
    },
    setLabelById(id, nodes = []) {
      for (const item of nodes) {
        if (item[this.valueField] === id && this.isLeafNode(item)) {
          this.selectedLabel = item[this.labelField];
          return true;
        }
        if (item[this.childrenField]) {
          if (this.setLabelById(id, item[this.childrenField])) {
            return true;
          }
        }
      }
      return false;
    }
  }
};
</script>


<style scoped>
  .tree-select-wrapper {
    width: 100%;
  }

  .tree-select-popover {
    max-height: 300px;
    overflow-y: auto;
    padding: 8px;
  }
</style>
